package com.rickpan.service;

import com.rickpan.dto.chat.*;
import com.rickpan.entity.ChatMessage;
import com.rickpan.entity.ChatSession;
import com.rickpan.exception.BusinessException;
import com.rickpan.repository.ChatMessageRepository;
import com.rickpan.repository.ChatSessionRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 聊天会话服务
 */
@Service
public class ChatSessionService {

    @Autowired
    private ChatSessionRepository chatSessionRepository;

    @Autowired
    private ChatMessageRepository chatMessageRepository;

    /**
     * 创建新会话
     */
    @Transactional
    public ChatSessionDTO createSession(Long userId, CreateSessionRequest request) {
        ChatSession session = new ChatSession();
        session.setUserId(userId);
        session.setTitle(request.getTitle());
        session.setModel(request.getModel());
        session.setMessageCount(0);
        session.setCreatedAt(LocalDateTime.now());
        session.setUpdatedAt(LocalDateTime.now());

        ChatSession savedSession = chatSessionRepository.save(session);
        return convertToDTO(savedSession);
    }

    /**
     * 获取用户的会话列表
     */
    public List<ChatSessionDTO> getUserSessions(Long userId, int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "updatedAt"));
        List<ChatSession> sessions = chatSessionRepository.findByUserIdOrderByUpdatedAtDesc(userId, pageable);
        
        return sessions.stream().map(session -> {
            ChatSessionDTO dto = convertToDTO(session);
            
            // 获取最后一条消息
            ChatMessage lastMessage = chatMessageRepository.findTopBySessionIdOrderByCreatedAtDesc(session.getId());
            if (lastMessage != null) {
                dto.setLastMessage(truncateMessage(lastMessage.getContent()));
                dto.setLastMessageRole(lastMessage.getRole());
                dto.setLastMessageTime(lastMessage.getCreatedAt());
            }
            
            return dto;
        }).collect(Collectors.toList());
    }

    /**
     * 获取会话详情（包含消息）
     */
    public ChatSessionDetailDTO getSessionDetail(Long userId, Long sessionId) {
        ChatSession session = chatSessionRepository.findByIdAndUserId(sessionId, userId);
        if (session == null) {
            throw new BusinessException("会话不存在或无权限访问");
        }

        ChatSessionDetailDTO dto = new ChatSessionDetailDTO();
        BeanUtils.copyProperties(session, dto);

        // 获取消息列表
        List<ChatMessage> messages = chatMessageRepository.findBySessionIdOrderByCreatedAtAsc(sessionId);
        List<ChatMessageDTO> messageDTOs = messages.stream()
                .map(this::convertMessageToDTO)
                .collect(Collectors.toList());
        
        dto.setMessages(messageDTOs);
        return dto;
    }

    /**
     * 更新会话标题
     */
    @Transactional
    public void updateSessionTitle(Long userId, Long sessionId, String title) {
        ChatSession session = chatSessionRepository.findByIdAndUserId(sessionId, userId);
        if (session == null) {
            throw new BusinessException("会话不存在或无权限访问");
        }

        session.setTitle(title);
        session.setUpdatedAt(LocalDateTime.now());
        chatSessionRepository.save(session);
    }

    /**
     * 删除会话
     */
    @Transactional
    public void deleteSession(Long userId, Long sessionId) {
        ChatSession session = chatSessionRepository.findByIdAndUserId(sessionId, userId);
        if (session == null) {
            throw new BusinessException("会话不存在或无权限访问");
        }

        // 删除会话及其所有消息（通过外键级联删除）
        chatSessionRepository.delete(session);
    }

    /**
     * 保存消息到会话
     */
    @Transactional
    public ChatMessageDTO saveMessage(Long userId, Long sessionId, SaveMessageRequest request) {
        ChatSession session = chatSessionRepository.findByIdAndUserId(sessionId, userId);
        if (session == null) {
            throw new BusinessException("会话不存在或无权限访问");
        }

        ChatMessage message = new ChatMessage();
        message.setSessionId(sessionId);
        message.setRole(request.getRole());
        message.setContent(request.getContent());
        message.setTokenCount(request.getTokenCount());
        message.setCreatedAt(LocalDateTime.now());

        ChatMessage savedMessage = chatMessageRepository.save(message);

        // 更新会话的消息数量和更新时间
        session.setMessageCount(session.getMessageCount() + 1);
        session.setUpdatedAt(LocalDateTime.now());
        chatSessionRepository.save(session);

        return convertMessageToDTO(savedMessage);
    }

    /**
     * 清空会话的所有消息
     */
    @Transactional
    public void clearSessionMessages(Long userId, Long sessionId) {
        ChatSession session = chatSessionRepository.findByIdAndUserId(sessionId, userId);
        if (session == null) {
            throw new BusinessException("会话不存在或无权限访问");
        }

        // 删除会话的所有消息
        chatMessageRepository.deleteBySessionId(sessionId);

        // 重置会话的消息数量和更新时间
        session.setMessageCount(0);
        session.setUpdatedAt(LocalDateTime.now());
        chatSessionRepository.save(session);
    }

    /**
     * 转换会话实体为DTO
     */
    private ChatSessionDTO convertToDTO(ChatSession session) {
        ChatSessionDTO dto = new ChatSessionDTO();
        BeanUtils.copyProperties(session, dto);
        return dto;
    }

    /**
     * 转换消息实体为DTO
     */
    private ChatMessageDTO convertMessageToDTO(ChatMessage message) {
        ChatMessageDTO dto = new ChatMessageDTO();
        BeanUtils.copyProperties(message, dto);
        return dto;
    }

    /**
     * 截断消息内容用于预览
     */
    private String truncateMessage(String content) {
        if (content == null) return "";
        return content.length() > 50 ? content.substring(0, 50) + "..." : content;
    }
}
